package com.zoro.interviewee.mq;

import com.rabbitmq.client.*;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeoutException;

/**
 * @author zhaoxingwu
 */
public class Test {


    public static void main(String[] args) throws IOException, TimeoutException {
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("192.168.187.131");
        factory.setPort(5672);
        factory.setUsername("admin");
        factory.setPassword("1");
        factory.setVirtualHost("/");

        Connection connection = factory.newConnection();
        // Channel 是不能线程共享的，可以使用spring channel pool
        // Channel 也是不推荐每次操作都打开一个新Channel 的
        Channel channel = connection.createChannel();
        MyConsumerAndPublisher publisher = new MyConsumerAndPublisher(channel, "FirstExchange", "FirstQueue",
                "FirstBindKey");
        publisher.init();

        for (int i = 0; i < 10; i++) {
            publisher.publish("publish-" + i + "-" + System.currentTimeMillis());
        }
    }
}

class MyConsumerAndPublisher {
    private final Channel channel;
    private final String exchangeName;
    private final String queueName;
    private final String bindKey;

    MyConsumerAndPublisher(Channel channel, String exchangeName, String queueName, String bindKey) {
        this.channel = channel;
        this.exchangeName = exchangeName;
        this.queueName = queueName;
        this.bindKey = bindKey;
    }

    void init() throws IOException {
        /*
        1. 为确保 publish,consume 之前exchange 与 queue 存在，这里可以声明一下，如果存在没有影响，如果不存在就会创建一个
        2. 但是如果声明之前服务器已经存在这个exchange 或者 queue ,那么声明时的 参数一定要和服务器保持一样，否则就会出错
         */
        Map<String, Object> arg = new HashMap<>();
//        arg.put("alternate-exchange", "2");
        this.channel.exchangeDeclare(exchangeName, BuiltinExchangeType.DIRECT, true, false, arg);

        // 这是另一种声明方式，如果服务器上没有这个exchange 就报错
        // reply-code=404, reply-text=NOT_FOUND - no exchange 'FirstExchange' in vhost '/', class-id=40, method-id=10
        //this.channel.exchangeDeclarePassive(exchangeName);

        this.channel.queueDeclare(queueName, true, false, false, arg);

        // 这是另一种声明队列的方法，如果会存在报错
        // reply-code=404, reply-text=NOT_FOUND - no queue 'FirstQueue' in vhost '/', class-id=50, method-id=10
        //this.channel.queueDeclarePassive(queueName);

        this.channel.queueBind(queueName, exchangeName, bindKey);
    }

    void publish(String msg) throws IOException {
        System.out.println("publish: " + msg);
        if (msg == null || msg.length() == 0) {
            return;
        }
        this.channel.basicPublish(exchangeName, bindKey, null, msg.getBytes(StandardCharsets.UTF_8));
    }


}
